package controllers;

import java.sql.SQLException;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import models.game.Game;
import models.players.Player;
import models.user.User;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import dao.UserDAO;

@Controller
public class LoginAndRegisterController {

	ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
	UserDAO userDao = (UserDAO) context.getBean("userDao");
	/*
	 * !!Screen at StartUp!!
	 */
	
	@RequestMapping("/")
	public String redirect(HttpServletRequest request) {
		if (request.getSession().getAttribute("loggedIn") == null) {
			return "LoginAndRegister";			
		} else if ((boolean)request.getSession().getAttribute("loggedIn") == true) {
			return "GameMenu";
		} else {
			return "LoginAndRegister";
		}
	}
	
	@RequestMapping("Menu")
	public String goToMenu(HttpServletRequest request){
		request.getSession().removeAttribute("game");
		request.getSession().removeAttribute("player");
		return "GameMenu";
	}
	
	@RequestMapping("/Logout")
	public String logout(HttpServletRequest request) {
		Game game = (Game) request.getSession().getAttribute("game");
		HashMap<String, Player> players = (HashMap<String, Player>) request.getSession().getAttribute("players");
		if (game!=null){
			game.setGameIsLost(true);
		}
		if (game==null && players != null && !players.isEmpty()){
			int oldTurnIndex = players.get(request.getSession().getId()).getTurnIndex();
			players.remove(request.getSession().getId());
			for (Player p : players.values())
			{
				if (p.getTurnIndex() > oldTurnIndex){
					p.decreaseTurnIndex();
				}
			}
			GameMenuController.decreaseTurnIndex();
		}
		request.getSession().invalidate();
		return "LoginAndRegister";
	}
	
	@RequestMapping("/WinnerPage")
	public String showWinner() {
		return "WinnerPage";
	}
	
	@RequestMapping("/LoserPage")
	public String showLoser() {
		return "LooserPage";
	}

	/*
	 * Check if user with these attributes exists. If true - enter the /GameMenu
	 * If false - return to LoginAndRegister.jsp again with attribute "loggedIn"
	 * = false!
	 */

	@RequestMapping("/LoginHandler")
	public String loginHandler(HttpServletRequest request) {
		String username = request.getParameter("username");
		String email = null;
		String password = request.getParameter("password");
		boolean isCorrect = validateInputData(username, password, email) && checkUser(request);
		if (isCorrect) {
			// if (true) {
			request.getSession().setAttribute("username",
					username);
			request.getSession().setAttribute("loggedIn", true);
			return "GameMenu";
		} else {
			request.setAttribute("LoginMessage",
					"Incorrect username/password! Please try again!");
			request.getSession().setAttribute("loggedIn", false);
			return "LoginAndRegister";
		}
	}

	@RequestMapping("/RegistrationHandler")
	public String registrationHandler(HttpServletRequest request) {
		String username = request.getParameter("usernameReg");
		String email = request.getParameter("emailReg");
		String password = request.getParameter("passwordReg");
		boolean isInputCorrect = validateInputData(username, password, email);
		boolean areUserAndMailFree = false;
		if (isInputCorrect
				&& password.equals(request.getParameter("passwordReg2"))) { // valid
																			// login
			try {
				areUserAndMailFree = userDao.areUsernameAndMailFree(username,
						email);
			} catch (DataAccessException | SQLException e) {
				// maybe some message here ..
				e.printStackTrace();
			}
			
			if (areUserAndMailFree) {
				User user = new User();
				user.setUsername(username);
				user.setPassword(password);
				user.setEmail(email);
				userDao.insertUserInDataSource(user);
				request.getSession().setAttribute("username", username);
				request.getSession().setAttribute("loggedIn", true);
				return "GameMenu";
			} else {
				request.setAttribute(
						"RegistrationUserMessage",
						"A user with the corresponding username/email already exists! Please try again with different username/email.");
				request.getSession().setAttribute("loggedIn", false);
				return "LoginAndRegister";
			}
			
		} else {
			request.setAttribute("RegistrationInputMessage",
					"Incorrect email/password! Please try again!");
			return "LoginAndRegister";
		}
		
	}

	/*
	 * Check if the input data is correctly entered.
	 */
	public boolean validateInputData(String username, String password, String email) {
		// Check if the input fields are correct
		boolean isCorrect = false;
		if (username.length() > 0 // check user and pass
				&& password.length() > 5) {
			isCorrect = true;
			if (email != null) { // if there is e-mail
															// input field
				isCorrect = validateEmail(email);
			}
		}
		return isCorrect;
	}

	/*
	 * Check if user exists in DB. If yes - check if the password i correct
	 * Otherwise send warning!
	 */

	public boolean checkUser(HttpServletRequest request) {
		boolean isCorrect = false;
		User user = new User();
		user.setUsername(request.getParameter("username"));
		user.setPassword(request.getParameter("password"));

		// check if the password is correct
		try {
			if (userDao.checkUserInDataSource(user))
				isCorrect = true;
		} catch (SQLException e) {
			isCorrect = false;
		} catch (DataAccessException exc) {
			isCorrect = false;
		}
		// request.setAttribute("LoginMessage", isCorrect ? ""
		// : "Incorrect input data! Try again!");
		return isCorrect;
	}

	/*
	 * Check if the email is correctly inputed!
	 */

	public boolean validateEmail(String email) {
		String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$";
		java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern);
		java.util.regex.Matcher m = p.matcher(email);
		return m.matches();
	}
}
